﻿using nRoute.Components.Composition.Adapters;
using System;
using System.Collections.Generic;

namespace nRoute.Components.Composition
{
    public interface IResourceCatalogEx
        : IResourceCatalog, IDisposable
    {
        // Resource Locators Related

        IResourceLocator GetResourceLocator(Type resourceType);

        IResourceLocator GetResourceLocator<T>();

        IResourceLocator GetResourceLocator(Type resourceType, string key);

        IResourceLocator GetResourceLocator<T>(string key);

        bool TryGetResourceLocator(Type resourceType, out IResourceLocator resourceLocator);

        bool TryGetResourceLocator<T>(out IResourceLocator resourceLocator);

        bool TryGetResourceLocator(Type resourceType, string key, out IResourceLocator resourceLocator);

        bool TryGetResourceLocator<T>(string key, out IResourceLocator resourceLocator);

        // Catalogs Related

        IEnumerable<IResourceLocator> GetResourceCatalog(Type resourceType);

        IEnumerable<IResourceLocator> GetResourceCatalog<T>();

        // Know Types Related
        
        bool IsKnownType(Type resourceType);

        bool IsKnownType<T>();

        void CatalogAsKnownType(Type resourceType);

        void CatalogAsKnownType<T>();

        // Add/Remove Related 

        bool CatalogResource(Type resourceType, IResourceLocator resourceLocator);

        bool CatalogResource<T>(IResourceLocator resourceLocator);

        bool CatalogResource(Type resourceType, string key, IResourceLocator resourceLocator, bool defaultResource);

        bool CatalogResource<T>(string key, IResourceLocator resourceLocator, bool defaultResource);

        bool CatalogDefaultResourceKey(Type resourceType, string key);

        bool CatalogDefaultResourceKey<T>(string key);

        bool UncatalogResource(Type resourceType, string key);

        bool UncatalogResource<T>(string key);

        // Adapters Related

        bool RegisterAdapter(Func<Type, bool> adapterPredicate, Func<Type, ILocatorAdapter> adapterFactory);

        bool UnregisterAdapter(Func<Type, bool> adapterPredicate);

        // Callback Related

        IObservable<CatalogChange> GetCatalogPublisher(Type resourceType);

        // Type Builder

        ITypeBuilder TypeBuilder { get; }
    }
}
